/*
 * Copyright (c) 2012 Aleksander Zotov, Benedikt Markt, Aliaksei Babkovich
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 *  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 *  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package simulation;

import gui.UserSettingsBean;

import java.io.Serializable;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import database.DatabaseManager;

import user.User;
import user.UserManager;
import utils.DateUtils;
import utils.Debug;
import utils.UserNotFoundException;

/**
 * Class representing a simulation
 * 
 * @author Aleksander Zotov
 * @author Benedikt Markt
 */
public class Simulation implements Serializable, CallbackInterface {

	private static final long serialVersionUID = 1L;

	private String name;
	private String description;
	private float collisionDistance;
	private String referenceSystem;
	private Date startTime;
	private Date endTime;
	private String username;
	private int collisionCount;
	private String[] refData;
	private String identifier;
	private Future<Integer> process;
	private int progress;
	private Date timeStamp;
	private String results;
	private Boolean running = true;

	public Simulation(String name, String description, float collisionDistance,
			Date startTime, Date endTime, String[] refData, User user) {
		this.name = name;
		this.description = description;
		this.collisionDistance = collisionDistance;
		this.referenceSystem = user.getReferenceSystem();
		this.startTime = startTime;
		this.endTime = endTime;
		this.refData = refData;
		this.identifier = UUID.randomUUID().toString();
		this.progress = 0;
		this.timeStamp = new Date();
		this.username = user.getName();
		this.results = ("Simulation Noch nicht abgeschlossen!");
	}

	public Simulation(String name, String description, float collisionDistance,
			Date startTime, Date endTime, String[] refData, String username,
			String referenceSystem, int collisionCount, String identifier,
			Date timeStamp, String results) {
		
		this.name = name;
		this.description = description;
		this.collisionDistance = collisionDistance;
		this.startTime = startTime;
		this.endTime = endTime;
		this.refData = refData;
		this.username = username;
		this.referenceSystem = referenceSystem;
		this.collisionCount = collisionCount;
		this.identifier = identifier;
		this.timeStamp = timeStamp;
		this.results = results;

	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
		DatabaseManager dbMan = new DatabaseManager();
		dbMan.storeSimulation(this);

	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
		DatabaseManager dbMan = new DatabaseManager();
		dbMan.storeSimulation(this);

	}

	public float getCollisionDistance() {
		return collisionDistance;
	}

	public String getReferenceSystem() {
		return referenceSystem;
	}

	public Date getStartTime() {
		return startTime;
	}

	public Date getEndTime() {
		return endTime;
	}

	public String getUsername() {
		return username;
	}

	public int getCollisionCount() {
		return collisionCount;
	}

	public void setCollisionCount(int collisionCount) {
		this.collisionCount = collisionCount;
		DatabaseManager dbMan = new DatabaseManager();
		dbMan.storeSimulation(this);

	}

	public String[] getRefDataArray() {
		return refData;
	}

	public String getRefData() {
		String refDataString = "";
		for (int i = 0; i < refData.length; i++) {
			refDataString += refData[i];
			refDataString += "<br/>";
		}
		return refDataString;
	}

	public int getRefCount() {
		if (refData[0].charAt(0) == '0') {
			return refData.length / 3;
		} else {
			return refData.length / 2;
		}
	}

	public String getIdentifier() {
		return identifier;
	}

	public Future<Integer> getProcess() {
		return process;
	}

	public void setProcess(Future<Integer> process) {
		this.process = process;
	}

	public int getProgress() {
		return progress;
	}

	public Date getTimeStamp() {
		return timeStamp;
	}

	public String getResults() {
		return results;
	}

	@Override
	public void setProgress(int progress) {
		Debug.log(Debug.TRACE, "Progress: " + progress + "% of User: "
				+ username);
		this.progress = progress;
		// UserSettingsBean.updateTable();

	}

	@Override
	public void setResults(String results, int collisions) {
		this.results = results;
		this.collisionCount = collisions;
		DatabaseManager dbMan = new DatabaseManager();
		// UserSettingsBean.updateTable();
		dbMan.storeSimulation(this);
	}

	@Override
	public void start() {
		running = true;
		UserManager userMan = UserManager.getInstance();
		try {
			userMan.getUser(this.username).setRunningSim(true);
		} catch (UserNotFoundException e) {
			Debug.log(Debug.ERROR, "Username not found in Simulation.start!");
		}

	}

	@Override
	public void end() {
		running = false;
		UserManager userMan = UserManager.getInstance();
		try {
			userMan.getUser(this.username).setRunningSim(false);
		} catch (UserNotFoundException e) {
			Debug.log(Debug.ERROR, "Username not found in Simulation.end!");
		}

	}
}
